library DateUtil;
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';


extension DateTimes on DateTime{
  static const int D_MINUTE  =  60;
  static const int D_HOUR   =     3600;
  static const int D_DAY    =    86400;
  static const int D_WEEK    =    604800;
  static const int D_YEAR    =    31556926;

  ///本地时间
  static DateTime localDate(){
    return DateTime.now();
  }

  /***************日期转换***********************/
  String dateStrWithFormat(String format){
    DateFormat formatter = DateFormat(format);
    return formatter.format(this);
  }

  /// 字符串转日期时间
  static DateTime? dateByDateStr(String dateStr){
    DateTime? dateTime = DateTime.tryParse(dateStr);
    dateTime = (dateTime!=null && dateTime.isUtc) ? dateTime?.dateWithHoursAfter(8) : dateTime;
    return dateTime;
  }

  /// 日期时间转毫秒
 int getDateMs(){
    return this.millisecondsSinceEpoch;
  }

  /// 日期时间字符串转毫秒
  static int? getDateMsByDateStr(String dateStr){
    DateTime? dateTime = DateTime.tryParse(dateStr);
    dateTime = (dateTime!=null && dateTime.isUtc) ? dateTime?.dateWithHoursAfter(8) : dateTime;
    return dateTime == null ? null : dateTime.millisecondsSinceEpoch;
  }

  /// 毫秒转日期时间
  static DateTime getDateTimeByMs(int milliseconds, {bool isUtc = false}){
    DateTime dateTime = new DateTime.fromMillisecondsSinceEpoch(milliseconds, isUtc: isUtc);
    return dateTime;
  }

  /// 毫秒转日期时间字符格式
  static String getDateStrByMs(int milliseconds,{required String format,bool isUtc = false}){
    DateTime dateTime = getDateTimeByMs(milliseconds, isUtc: isUtc);
    return dateTime.dateStrWithFormat(format);
  }

  /***************相对日期***********************/
  /// 今年之后几年的日期
  static DateTime dateWithYearsFromNow(int years) {
    DateTime date = localDate();
    return date.dateWithYearsAfter(years);
  }
  DateTime dateWithYearsAfter(int years){
    return DateTime(this.year + years, this.month, this.day, this.hour, this.minute,this.second,this.millisecond,this.microsecond);
  }
  /// 今年之前几年的日期
  static DateTime dateWithYearsBeforeNow(int years){
    DateTime date = localDate();
    return date.dateWithYearsBefore(years);
  }
  DateTime dateWithYearsBefore(int years){
    return DateTime(this.year - years, this.month, this.day, this.hour, this.minute,this.second,this.millisecond,this.microsecond);
  }
  /// 今月之后几月的日期
  static DateTime dateWithMonthsFromNow(int months){
    DateTime date = localDate();
    return date.dateWithMonthsAfter(months);
  }
  DateTime dateWithMonthsAfter(int months){
    return DateTime(this.year, this.month + months, this.day, this.hour, this.minute,this.second,this.millisecond,this.microsecond);
  }
  /// 今月之前几月的日期
  static DateTime dateWithMonthsBeforeNow(int months){
    DateTime date = localDate();
    return date.dateWithMonthsBefore(months);
  }

  DateTime dateWithMonthsBefore(int months){
    return DateTime(this.year, this.month - months, this.day, this.hour, this.minute,this.second,this.millisecond,this.microsecond);
  }
  /// 今天之后几天的日期
  static DateTime dateWithDaysFromNow(int days){
    DateTime date = localDate();
    return date.dateWithDaysAfter(days);
  }

  DateTime dateWithDaysAfter(int days){
    return this.add(Duration(days: days));
  }
  /// 今天之前的日期
  static DateTime dateWithDaysBeforeNow(int days){
    DateTime date = localDate();
    return date.dateWithDaysBefore(days);
  }

  DateTime dateWithDaysBefore(int days){
    return this.subtract(Duration(days: days));
  }
  /// 明天
  static DateTime dateTomorrow(){
    return dateWithDaysFromNow(1);
  }

  /// 昨天
  static DateTime dateYesterday(){
    return dateWithDaysFromNow(-1);
  }

  ///当前之后几小时的日期
  static DateTime dateWithHoursFromNow(int hours) {
    DateTime date = localDate();
    return date.dateWithHoursAfter(hours);
  }
  DateTime dateWithHoursAfter(int hours)
  {
    return this.add(Duration(hours: hours));
  }
  /// 当前之前几小时的日期
  static DateTime dateWithHoursBeforeNow(int hours) {
    DateTime date = localDate();
    return date.dateWithHoursBefore(hours);
  }

  DateTime dateWithHoursBefore(int hours)
  {
    return this.subtract(Duration(hours: hours));
  }
  /// 当前之后几分钟
  static DateTime dateWithMinutesFromNow(int minutes){
    DateTime date = localDate();
    return date.dateWithMinutesAfter(minutes);
  }

  DateTime dateWithMinutesAfter(int minutes)
  {
    return this.add(Duration(minutes: minutes));
  }
  /// 当前之前几分钟
  static DateTime dateWithMinutesBeforeNow(int minutes){
    DateTime date = localDate();
    return date.dateWithMinutesBefore(minutes);
  }

  DateTime dateWithMinutesBefore(int minutes)
  {
    return this.subtract(Duration(minutes: minutes));
  }
  /***************周处理***********************/
  ///今年第几周
  int weekOfYear() {
    ///当前选中时间 周几
    var currentWeekDay = this.weekday;

    ///周四
    int EPOCH_WEEK_DAY = DateTime.thursday;

    DateTime epoch = DateTime.utc(this.year);
    print("epoch:$epoch");
    int offset = EPOCH_WEEK_DAY - currentWeekDay;

    int delta =  - offset;

    int week = (this.difference(epoch).inDays - delta) ~/ 7 + 1;
    return week;
  }
  //周几
  String weekdayWithDate(DateTime date){
    //声明星期变量
    var weekday = [" ", "一", "二", "三", "四", "五", "六", "日"];
    //变量直接调用日期函数weekday
    return weekday[date.weekday];
  }
  /***************日期比较***********************/
  /// 是否同周
  bool isSameWeek(DateTime dateB){
    if(this.weekOfYear() != this.weekOfYear()) return false;
    return this.secondsOffset(dateB).abs() < D_WEEK;
  }

  ///是否这周
  bool isThisWeek(){
    return this.isSameWeek(localDate());
  }
  bool isNextWeek()
  {
    return this.isSameWeek(localDate().add(Duration(days: 7)));
  }

  bool isLastWeek(DateTime date)
  {
    return this.isSameWeek(localDate().subtract(Duration(days: 7)));
  }

  /// 是否是相同日期时间
  bool isSameDate(DateTime dateB){
    return this.compareTo(dateB) == 0;
  }

  ///是否同一天
  bool isSameDay(DateTime dateB){
    return
      this.year == dateB.year &&
          this.month == dateB.month &&
          this.day == dateB.day;
  }
  /// 是否是今天
  bool isToday(){
    return DateUtils.isSameDay(localDate(), this);
  }

  /// 是否是明天
  bool isTomorrow(){
    DateTime tomorrow = dateWithDaysFromNow(1);
    return DateUtils.isSameDay(tomorrow, this);
  }

  /// 是否是昨天
  bool isYesterday(){
    DateTime yesterday = dateWithDaysBeforeNow(1);
    return DateUtils.isSameDay(yesterday, this);
  }

  ///是否同一月
  bool isSameMonth(DateTime dateB){
    return
      this.year == dateB.year &&
          this.month == dateB.month;
  }
  /// 是否这个月
  bool isThisMonth(){
    return DateUtils.isSameMonth(localDate(), this);
  }

  /// 是否上个月
  bool isLastMonth(){
    DateTime lastMonth = dateWithMonthsBeforeNow(1);
    return DateUtils.isSameMonth(lastMonth, this);
  }

  /// 是否下一个月
  bool isNextMonth(){
    DateTime nextMonth = dateWithMonthsFromNow(1);
    return DateUtils.isSameMonth(nextMonth, this);
  }


  ///是否同一年
  bool isSameYear(DateTime date){
    return this.year == date.year;
  }

  /// 是否是这年
  bool isThisYear(){
    return this.year == localDate().year;
  }

  /// 是否是下一年
  bool isNextYear(){
    final bool isLeapYear = (year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0);
    return this.year == localDate().add(Duration(days:isLeapYear ? 366 : 365));
  }

  /// 是否是上一年
  bool isLastYear(){
    final bool isLeapYear = (year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0);
    return this.year == localDate().subtract(Duration(days:isLeapYear ? 366 : 365));
  }

  /// 未来
  bool isInFuture(){
    return this.isAfter(localDate());
  }

  /// 过去
  bool isInPast(){
    return this.isBefore(localDate());
  }
  /********************日期相对差值***************************/

  /// this 和 dateB 相差多少天
  int daysOffset(DateTime dateB) {
    Duration diff = this.difference(dateB);
    return diff.inDays;
  }

  /// this 和 dateB 相差多少小时
  int hoursOffset(DateTime dateB) {
    Duration diff = this.difference(dateB);
    return diff.inHours;
  }

  /// this 和 dateB 相差多少分钟
  int minutesOffset(DateTime dateB){
    Duration diff = this.difference(dateB);
    return diff.inMinutes;
  }

  /// this 和 dateB 相差多少秒
  int secondsOffset(DateTime dateB) {
    Duration diff = this.difference(dateB);
    return diff.inSeconds;
  }

  /// this 和 dateB 相差多少毫秒
  int millisOffset(DateTime dateB) {
    Duration diff = this.difference(dateB);
    return diff.inMilliseconds;
  }

  /// dateA 和 dateB 相差多少微秒
  int microsOffset(DateTime dateB) {
    Duration diff = this.difference(dateB);
    return diff.inMicroseconds;
  }
}